package com.filetransfer.controller;

import com.filetransfer.config.FileStorageConfig;
import com.filetransfer.model.FileInfo;
import com.filetransfer.service.FileTransferService;
import com.filetransfer.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@Slf4j
public class FileTransferController {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FileTransferController.class);
    
    @Autowired
    private FileTransferService fileTransferService;
    
    @Autowired
    private FileStorageConfig fileStorageConfig;
    
    @Autowired
    private FileService fileService;
    
    /**
     * 显示文件上传页面
     */
    @GetMapping("/")
    public String index() {
        return "index";
    }
    
    /**
     * 处理文件上传
     */
    @PostMapping("/upload")
    public ResponseEntity<Map<String, Object>> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                Map<String, Object> response = new HashMap<>();
                response.put("message", "请选择要上传的文件");
                response.put("status", "error");
                return ResponseEntity.badRequest().body(response);
            }

            // 获取文件名和文件信息
            String fileName = file.getOriginalFilename();
            long fileSize = file.getSize();
            String fileType = file.getContentType();
            
            // 生成唯一的文件ID
            String fileId = UUID.randomUUID().toString();
            
            // 打印文件详细信息
            log.info("===== 收到文件上传请求 =====");
            log.info("文件ID: {}", fileId);
            log.info("文件名: {}", fileName);
            log.info("文件大小: {} bytes", fileSize);
            log.info("文件类型: {}", fileType);
            log.info("文件大小(格式化): {} KB", fileSize / 1024);
            log.info("文件是否为空: {}", file.isEmpty());
            log.info("==========================");
            
            // 确保上传目录存在
            String uploadDir = fileStorageConfig.getUploadDir();
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            
            // 创建目标文件路径
            String fileExtension = fileName.contains(".") ? 
                fileName.substring(fileName.lastIndexOf('.')) : "";
            String storageFileName = fileId + fileExtension;
            Path targetLocation = uploadPath.resolve(storageFileName);
            
            // 保存文件
            file.transferTo(targetLocation.toFile());
            log.info("文件已保存到: {}", targetLocation.toString());
            
            // 保存文件信息到服务
            fileService.saveFile(fileId, fileName, targetLocation.toString(), fileSize, fileType);
            
            // 记录到日志后可以进行其他处理（如模拟传输）
            File tempFile = targetLocation.toFile();
            fileTransferService.startTransfer(tempFile);
            
            Map<String, Object> response = new HashMap<>();
            response.put("message", "文件上传成功并开始传输");
            response.put("status", "success");
            response.put("fileId", fileId);
            response.put("fileName", fileName);
            response.put("fileSize", fileSize);
            return ResponseEntity.ok(response);
            
        } catch (IOException e) {
            log.error("文件上传失败: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("message", "文件上传失败: " + e.getMessage());
            response.put("status", "error");
            return ResponseEntity.badRequest().body(response);
        } catch (Exception e) {
            log.error("处理请求时出错: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("message", "处理请求时出错: " + e.getMessage());
            response.put("status", "error");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取所有文件列表
     */
    @GetMapping("/files")
    public ResponseEntity<List<FileInfo>> getFileList() {
        try {
            List<FileInfo> files = fileService.getAllFiles();
            return ResponseEntity.ok(files);
        } catch (Exception e) {
            log.error("获取文件列表失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
    
    /**
     * 下载文件
     */
    @GetMapping("/files/{fileId}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileId) {
        try {
            // 获取文件信息
            FileInfo fileInfo = fileService.getFileById(fileId)
                .orElseThrow(() -> new RuntimeException("文件不存在: " + fileId));
            
            // 创建资源对象
            Path filePath = Paths.get(fileInfo.getFilePath());
            Resource resource = new UrlResource(filePath.toUri());
            
            if (resource.exists()) {
                // 确定内容类型
                String contentType = Files.probeContentType(filePath);
                if (contentType == null) {
                    contentType = "application/octet-stream";
                }
                
                // 构建响应头
                HttpHeaders headers = new HttpHeaders();
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileInfo.getFileName(), StandardCharsets.UTF_8.toString()));
                headers.add(HttpHeaders.CONTENT_TYPE, contentType);
                headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileInfo.getFileSize()));
                
                log.info("下载文件: {} (ID: {})", fileInfo.getFileName(), fileId);
                
                return ResponseEntity.ok()
                    .headers(headers)
                    .body(resource);
            } else {
                log.error("文件不存在于磁盘: {}", fileInfo.getFilePath());
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            log.error("无效的文件URL: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("文件下载失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 删除文件
     */
    @DeleteMapping("/files/{fileId}")
    public ResponseEntity<Map<String, Object>> deleteFile(@PathVariable String fileId) {
        try {
            boolean deleted = fileService.deleteFile(fileId);
            Map<String, Object> response = new HashMap<>();
            
            if (deleted) {
                response.put("message", "文件删除成功");
                response.put("status", "success");
                return ResponseEntity.ok(response);
            } else {
                response.put("message", "文件不存在或删除失败");
                response.put("status", "error");
                return ResponseEntity.notFound().build();
            }
        } catch (Exception e) {
            log.error("文件删除失败: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("message", "文件删除失败: " + e.getMessage());
            response.put("status", "error");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
}